/**
 * @desc UTF-8编码
 */
function utf8_encode(str: string) {
  let utf8text = ''
  for (let n = 0; n < str.length; n++) {
    const c = str.charCodeAt(n)
    if (c < 128) {
      utf8text += String.fromCharCode(c)
    } else if (c > 127 && c < 2048) {
      utf8text += String.fromCharCode((c >> 6) | 192)
      utf8text += String.fromCharCode((c & 63) | 128)
    } else {
      utf8text += String.fromCharCode((c >> 12) | 224)
      utf8text += String.fromCharCode(((c >> 6) & 63) | 128)
      utf8text += String.fromCharCode((c & 63) | 128)
    }
  }
  return utf8text
}

/**
 * @desc UTF-8解码
 */
function utf8_decode(utf8text: string) {
  let str = ''
  let i = 0
  let c, c2, c3
  while (i < utf8text.length) {
    c = utf8text.charCodeAt(i)
    if (c < 128) {
      str += String.fromCharCode(c)
      i++
    } else if (c > 191 && c < 224) {
      c2 = utf8text.charCodeAt(i + 1)
      str += String.fromCharCode(((c & 31) << 6) | (c2 & 63))
      i += 2
    } else {
      c2 = utf8text.charCodeAt(i + 1)
      c3 = utf8text.charCodeAt(i + 2)
      str += String.fromCharCode(
        ((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)
      )
      i += 3
    }
  }
  return str
}

/**
 * @desc Base64编码
 */
function b64_encode(str: string) {
  return str ? window.btoa(utf8_encode(str)) : str
}

/**
 * @desc Base64解码
 */
function b64_decode(str: string) {
  return str ? utf8_decode(window.atob(str)) : str
}

export { b64_decode, b64_encode, utf8_decode, utf8_encode }
